home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / prog / yamp2.zip / VDOUB.TEX < prev    next >
Text File  |  1992-01-11  |  8KB  |  219 lines

  1. \chapter{Virtual Vector of Doubles}
  2.  
  3. The virtual matrix class is derived from a class of a
  4. vector of doubles stored in the virtual memory system. The
  5. virtual vector gives the matrix class access to the virtual
  6. memory. Holub\cite{Ho:pr} developed a class of integer
  7. vectors with a set of overloaded operators. He created the
  8. class to ease access to the vmm, and demonstrate several
  9. aspects of using classes. Here, the integer class was
  10. rewritten for doubles, and the operators were stripped in
  11. favor of using them on the matrices.
  12.  
  13. Again, the virtual vector should be considered another
  14. intermediate step in creating the virtual matrix class. It is
  15. not needed in the in-ram version, since matrices are allocated
  16. on the heap. Instead a structure is used to store a vector
  17. allocated by calloc, and the number of references to the
  18. structure. This will be explaned in more detail in the chapter
  19. on the stack.
  20.  
  21. \section{vdoub}
  22. The virtual vector of doubles\index{vdoub } is declared in
  23. the following class statement
  24.  
  25. \begin{verbatim}
  26. class vdoub{
  27.  
  28.   protected:
  29.   
  30.     unsigned signature;// garbage flag;
  31.     hdr *hdr;          // virtual memory handle
  32.     double *cur_ele;   // current element
  33.     long  cur_index;   // current index
  34.     //static int nobj;
  35.  
  36.     friend double val( vdoub &v);
  37.   
  38.   public:
  39.   
  40.     int Garbage( void ){ return  !( signature == SIGNATURE ); }
  41.  
  42.     vdoub ( long array_size );
  43.     vdoub ( void );
  44.     vdoub ( vdoub &src );
  45.     ~vdoub( void );
  46.  
  47.     double v( long index );          // get value
  48.     vdoub& operator[]( long index ); // store value
  49.     double operator = ( double d );
  50.     double operator = ( vdoub &v );
  51. };
  52. \end{verbatim}
  53.  
  54. Note that the access to the vmm is in a protected section
  55. of the definition. The matrix class needs access to some of
  56. these elements. 
  57.  
  58. \subsection{Protected Part of a vdoub}
  59. The signature is a garbage flag. It is set to zero when the
  60. vector is deleted. It also serves as a check for the front of
  61. the class being overwritten by rogue functions. The hdr is
  62. a pointer to a vmm header created by vmalloc. 
  63.  
  64. The cur\_ele is a pointer to the current element being
  65. addressed in the virtual vector. The cur\_index is the index
  66. of the current index in the vector. Note the index is a
  67. long, so index operations must be cast on long integers.  
  68. These two variables help control which buffer is stored in
  69. the vmem of the hdr. The member function val() returns the
  70. current value.
  71.  
  72. The static integer, nobj, counts the number of active
  73. vectors. If it is zero, then the vmm system is initialized
  74. in the constructors. The constructors increment nobj and
  75. the destructors decrement nobj.
  76.  
  77. The in-ram version\index{vdoub!IN-RAM vdoub} also sets up a
  78. virtual vector structure, but its memory is allocated entirely
  79. on the heap. The structure is
  80. \begin{verbatim}
  81. typedef struct vdoub{
  82.     int nrefs;
  83.     double *mm;
  84. } vdoub;
  85. \end{verbatim}
  86. The variable, nrefs, stores the number of references to this
  87. vector. The vector pointer *mm is not freed until nrefs is zero.
  88. Note this is a typedef instead of class, so the in-ram virtual
  89. matrix is not derived from vdoub.
  90.  
  91.  
  92. \subsection{Public Parts of a vdoub}
  93. The public functions give access to the vmm. The function
  94. Garbage()\index{vdoub!Garbage()} simply checks if the signature is
  95. correct. This indicates that the vdoub is likely intact and
  96. active. 
  97.  
  98. The constructors\index{vdoub!constructors} accept void,
  99. long or vdoub\&  arguments.  The default constructor
  100. accepts a void. It allocates a hdr on the vmm with one
  101. double. The second constructor does the same, but the hdr
  102. contains array\_size elements. The constructor with a vdoub
  103. reference argument copies one vdoub into another. Each
  104. constructor increments nobj, and calls
  105. vopen()\index{vmm!vopen()} if nobj is zero.
  106.  
  107. The destructor\index{vdoub!destructor} frees the header. If
  108. the hdr is freed with error, the system stops. Otherwise,
  109. the signature is set to zero and nobj is decremented. If
  110. nobj is decremented to zero, then vclose()\index{vmm!vclose()}
  111. is called. Note that this does not guarantee that vclose()
  112. will be called when the program leaves the main() function
  113. because some virtual matrices are constructed outside of
  114. the scope of main(). The matrix stack dispatcher is a
  115. pointer to the base of a stack of matrices. It is allocated
  116. outside of the function main() so it will not be destroyed
  117. upon leaving main().  Thus, vclose() must be called before
  118. leaving main(). The next time the destructor is called,
  119. vfree() will return an error so the program will exit
  120. through the last destructor call.
  121.  
  122. The function v()\index{vdoub!v()} gets the value at index.
  123. It calls vread() and returns the value. It also sets
  124. cur\_index to index, and stores the current value in
  125. *cur\_ele. Note that the call to vread() may change the
  126. page the buffer in vmem.
  127.  
  128. The brackets operator\index{vdoub![] operator} provides
  129. the same function as v(), but you can use the vector
  130. notation to do it. However it is basically very different
  131. than accessing an element on the heap, or some offset from
  132. a pointer base. The call to vread() shifts a new page into
  133. RAM if necessary. The normal use of the brackets operator
  134. just accesses RAM. This has side effects in the assignment
  135. operation on virtual vectors.
  136.  
  137. The difference between v() and the brackets operator is
  138. they have different return types. v() returns a double and
  139. vdoub::operator[] returns a reference to another vdoub. To
  140. quote Holub: 
  141. \begin{quote}
  142. The brackets operator is a {\em selector } operator. It
  143. sets things up so that the next operation can access the
  144. array element selected by the previous bracket. If the {\em
  145. next} operation modifies the array element, then that
  146. operation sets the dirty bit.
  147. \end{quote}  
  148.  
  149. \section{Assignment in vdoub} 
  150.  
  151. Assignment\index{vdoub!=} takes two forms for virtual vectors. The problem
  152. is to make the code work for saying \verb+ vect[i] = 5+ or
  153. for saying \verb+ vect1 = vect2+. The first form of
  154. assignment is 
  155. \begin{verbatim}
  156. double vdoub::operator = ( double d )
  157.   {
  158.     if ( Garbage() ) {
  159.       perror("VMS assignment error, source is Garbage(=)");
  160.       exit(1);
  161.     }
  162.     *cur_ele = d;
  163.     vdirty( hdr );
  164.     return d;
  165.   }
  166. \end{verbatim}
  167.  
  168. The functional form of \verb+ vect[i] = 5+ is 
  169. \verb+ (vect.operator[](i)).operator=(5)+. First the
  170. brackets operator is called, which sets the current index
  171. to i.  Since the bracket operator returns a reference to a
  172. vdoub, the vdoub::operator=(5) is called.  The current
  173. element of the returned vdoub is set to 5. Next the buffer
  174. is declared dirty, and a the 5 is returned.
  175.  
  176. The other form of assignment copies a double vector to
  177. another. It disposes the left operand hdr if it already
  178. exists, then allocates a new hdr. Then it copies the
  179. contents from v to the new hdr. The code is given by
  180.  
  181. \begin{verbatim}
  182. double vdoub::operator = ( vdoub &v)
  183. // copy vector v to vector t
  184.   {
  185.      if( v.Garbage() ){
  186.        perror("VMS copy error, source is Garbage");
  187.        exit(1);
  188.      }
  189.     if( !Garbage() ) vfree( hdr ); // replace hdr if t is active
  190.  
  191.     double *p;
  192.     long numele = vele( v.hdr );
  193.     signature = SIGNATURE;
  194.     *cur_ele = *v.cur_ele;
  195.     cur_index = v.cur_index;
  196.     
  197.     if ( !(hdr = vmalloc( numele, sizeof( double )))) {
  198.       perror(" VMS copy allocation error");
  199.       exit(1);
  200.     }
  201.     while( --numele >= 0 ) {
  202.       if ( !(p = (double *) vread( v.hdr, numele))){
  203.         perror("VMS copy-access( read ) error");
  204.         exit(1);
  205.       }
  206.       if (!vwrite(hdr, numele,(char *)p)){
  207.         perror("VMS copy-access( write ) error");
  208.         exit(1);
  209.       }
  210.     }
  211.     return *cur_ele;
  212.   }
  213. \end{verbatim}
  214.  
  215. This code fragment really emphasizes how well the vdoub
  216. class insulates the user from the vmm system. You don't
  217. have to remember all of the arguments for vread, vwrite,
  218. and vmalloc. You also have a good deal of error checking
  219. embedded in the assignment operators.